﻿using System;
using System.Collections.Generic;
using System.Text;

namespace MyLib.Utils
{
    public class FilterBuilder
    {
        StringBuilder _builder = new StringBuilder();
        public void AddLike(string key, object value)
        {
            if (IsNullOrEmpty(value))
            {
                return;
            }
            string val = GetValue(value);
            _builder.AppendFormat(" and {0} like '%{1}%'",key,val);
        }

        public void AddEqual(string key, object value)
        {
            if (IsNullOrEmpty(value))
            {
                return;
            }
            string val = GetValue(value);
            _builder.AppendFormat(" and {0} = '{1}'", key, val);
        }

        public void AddIn(string key, string[] collections)
        {
            if (collections.Length==0)
            {
                _builder.AppendFormat(" and 1<>1 ");
                return;
            }
            string str = "";
            foreach (string col in collections)
            {
                str += ",'" + GetValue(col)+"'";
            }
            str = str.TrimStart(',');
            _builder.AppendFormat(" and {0} in ({1})", key, str);
        }

        public void AddScope(string key, object startValue,object endValue)
        {
            if (IsNullOrEmpty(startValue) && IsNullOrEmpty(endValue))
            {
                return;
            }
            string startVal = GetValue(startValue);
            string endVal = GetValue(endValue);
            DateTime startDate;
            DateTime endDate;
            if (DateTime.TryParse(startVal, out startDate))
            {
                startVal = startDate.ToString("yyyy/MM/dd 0:00:00");
            }
            if (DateTime.TryParse(endVal, out endDate))
            {
                endVal = endDate.ToString("yyyy/MM/dd 23:59:59");
            }

            if (IsNullOrEmpty(startValue))
            {
                _builder.AppendFormat(" and {0} <= '{1}' ", key,  endVal);
            }
            else if (IsNullOrEmpty(endValue))
            {
                _builder.AppendFormat(" and {0} >= '{1}' ", key, startVal);
            }
            else
            {
                _builder.AppendFormat(" and {0} between '{1}' and '{2}'", key, startVal, endVal);
            }
        }

        public StringBuilder InnerStringBuilder
        {
            get
            {
                return _builder;
            }
        }

        public override string ToString()
        {
            return _builder.ToString();
        }

        public string ToFilterString()
        {
            string str = _builder.ToString();
            if (!str.ToUpper().StartsWith("WHERE"))
            {
                str = " WHERE 1=1 " + str;
            }
            return str;
        }

        bool IsNullOrEmpty(object value)
        {
            if (value == null)
            {
                return true;
            }
            if (string.IsNullOrEmpty(value.ToString()))
            {
                return true;
            }
            return false;
        }

        string GetValue(object value)
        {
            string returnValue = "";
            if (value == null)
            {
                return "";
            }
            switch (value.GetType().Name)
            {
                case "String":
                    {
                        returnValue = ((string)value).Replace("'", "''");
                        break;
                    }
                case "DateTime":
                    {
                        returnValue = ((DateTime)value).ToString("yyyy/MM/dd hh:mm:ss");
                        break;
                    }
                case "DBNull":
                    {
                        returnValue = "NULL";
                        break;
                    }
                case "Boolean":
                    {
                        returnValue = (bool)value ? "1" : "0";
                        break;
                    }
                default:
                    {
                        returnValue = value.ToString();
                        break;
                    }
            }
            
            return returnValue;
        }
    }
}
